package dataModifiers;

import inputs.Input;

import java.util.LinkedList;
import java.util.List;

import management.UpdateManager;

/**
 * Singleton factory class for creating Modifiers.
 * Creating Modifiers through this class ensures they are added to the UpdateManager.
 * 
 * @author Dylan James
 *
 */
public class ModifierFactory {
	private static ModifierFactory instance;
	
	private static UpdateManager updateManager;
	
	
	
	private ModifierFactory()
	{
		updateManager = UpdateManager.getUpdateManager();
	}
	
	/**
	 * @return An instance of the Modifier Factory.
	 */
	public static ModifierFactory getFactory()
	{
		if (instance == null)
		{
			instance = new ModifierFactory();
		}
		
		return instance;
	}
	
	/**
	 * Adds an Modifier to the update management
	 * @param mod Modifier to add
	 * @param update True if this Modifier should be automatically updated each tick.
	 */
	private void Add(Modifier mod, boolean update)
	{
		updateManager.Add(mod, update);
	}

	/**
	 * Creates an Average and adds it to the Update Management.
	 * @param inputs The inputs for the Average.
	 * @param update Whether the Average should be automatically updated each tick.
	 * @return The created average.
	 */
	public Average createAverage(List<Input> inputs, boolean update)
	{
		Average average = new Average(inputs);
		
		Add(average, update);
		
		return average;
	}
	
	/**
	 * Creates an Average and adds it to the Update Management.
	 * Automatically updates it each tick.
	 * @param inputs The inputs for the Average.
	 * @return The created average.
	 */
	public Average createAverage(List<Input> inputs)
	{
		return createAverage(inputs, true);
	}
	
	/**
	 * Creates a HighPass and adds it to the Update Management.
	 * @param inputs The inputs for the HighPass.
	 * @param update Whether the HighPass should be automatically updated each tick.
	 * @return The created HighPass.
	 */
	public HighPass createHighPass(List<Input> inputs, boolean update)
	{
		HighPass highPass = new HighPass(inputs);
		
		Add(highPass, update);
		
		return highPass;
	}
	
	/**
	 * Creates a HighPass and adds it to the Update Management.
	 * Automatically updates it each tick.
	 * @param inputs The inputs for the HighPass.
	 * @return The created HighPass.
	 */
	public HighPass createHighPass(List<Input> inputs)
	{
		return createHighPass(inputs, true);
	}
	
	/**
	 * Creates a LowPass and adds it to the Update Management.
	 * @param inputs The inputs for the LowPass.
	 * @param update Whether the LowPass should be automatically updated each tick.
	 * @return The created LowPass.
	 */
	public LowPass createLowPass(List<Input> inputs, boolean update)
	{
		LowPass lowPass = new LowPass(inputs);
		
		Add(lowPass, update);
		
		return lowPass;
	}
	
	/**
	 * Creates a LowPass and adds it to the Update Management.
	 * Automatically updates it each tick.
	 * @param inputs The inputs for the LowPass.
	 * @return The created LowPass.
	 */
	public LowPass createLowPass(List<Input> inputs)
	{
		return createLowPass(inputs, true);
	}
	
	/**
	 * Creates a RandomInRange and adds it to the Update Management.
	 * @param inputs The inputs for the RandomInRange.
	 * @param update Whether the RandomInRange should be automatically updated each tick.
	 * @return The created RandomInRange.
	 */
	public RandomInRange createRandomInRange(List<Input> inputs, boolean update)
	{
		RandomInRange rir = new RandomInRange(inputs);
		
		Add(rir, update);
		
		return rir;
	}
	
	/**
	 * Creates a RandomInRange and adds it to the Update Management.
	 * Automatically updates it each tick.
	 * @param inputs The inputs for the RandomInRange.
	 * @return The created RandomInRange.
	 */
	public RandomInRange createRandomInRange(List<Input> inputs)
	{
		return createRandomInRange(inputs, true);
	}
	
	/**
	 * Creates a RandomOfInputs and adds it to the Update Management.
	 * @param inputs The inputs for the RandomOfInputs.
	 * @param update Whether the RandomOfInputs should be automatically updated each tick.
	 * @return The created RandomOfInputs.
	 */
	public RandomOfInputs createRandomOfInputs(List<Input> inputs, boolean update)
	{
		RandomOfInputs randOfInputs = new RandomOfInputs(inputs);
		
		Add(randOfInputs, update);
		
		return randOfInputs;
	}
	
	/**
	 * Creates a RandomOfInputs and adds it to the Update Management.
	 * Automatically updates it each tick.
	 * @param inputs The inputs for the RandomOfInputs.
	 * @return The created RandomOfInputs.
	 */
	public RandomOfInputs createRandomOfInputs(List<Input> inputs)
	{
		return createRandomOfInputs(inputs, true);
	}
	
	/**
	 * Creates a Sum and adds it to the Update Management.
	 * @param inputs The inputs for the Sum.
	 * @param update Whether the Sum should be automatically updated each tick.
	 * @return The created Sum.
	 */
	public Sum createSum(List<Input> inputs, boolean update)
	{
		Sum sum = new Sum(inputs);
		
		Add(sum, update);
		
		return sum;
	}
	
	/**
	 * Creates a Sum and adds it to the Update Management.
	 * Automatically updates it each tick.
	 * @param inputs The inputs for the Sum.
	 * @return The created Sum.
	 */
	public Sum createSum(List<Input> inputs)
	{
		return createSum(inputs, true);
	}

}
